/*
 * 生产消费模型
 *
 * 内部包含线程池和任务缓冲区，对外提供push接口
 *
 **/

#pragma once

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include "data.hh"
#include "util.hh"
#include "task.hh"
#include "queue.hh"

namespace cloud
{

class cp_model
{
    // The queue store the smart pointer to task 
    // for polymorphic invocation.
    using task_ptr = std::shared_ptr<task>;

public:
    static cp_model& instance(size_t size = config::instance().thread_num())
    {
        static cp_model cp(size);
        return cp;
    }

    void push(task_ptr t)
    {
        _queue.push(t);

        easylog::debug("cp_model push a task succ");
    }

private:
    cp_model(size_t size)
    {
        for (int i = 0; i < size; i++)
        {
            _thpool.emplace_back(&cp_model::routine, this);
            _thpool[i].detach();
        }

        easylog::info("cp_model instance created");
    }

    void routine()
    {
        while (true)
        {
            task_ptr t;
            _queue.pop(t);
            (*t)();

            easylog::debug("cp_model handle a task succ");
        }
    }

    cp_model(const cp_model&) = delete;
    cp_model& operator=(const cp_model&) = delete;

private:
    std::vector<std::thread> _thpool;
    loop_queue<task_ptr> _queue;
};

}
